﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Keepo.Models.Services;
using Infrastructure.Data;
using Keepo.Models;
using System.Drawing;
using System.Web;
using System.IO;

namespace Keepo.Helpers
{
    public class RenderHelper
    {
        static public Template2ProductMap Template2ProductByDesignPageId(int templatePageId, int designPageId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                Template2ProductMap map = new Template2ProductMap();

                DesignPage designPage = repository.GetByKey<DesignPage>(designPageId);
                DesignableProduct product = designPage.DesignableProduct;
                ProductPage productPage = designPage.ProductPage;
                PrinterPage printerPage = product.PrinterPages.FirstOrDefault(p => p.PageIdx == designPage.ProductPage.PageIdx);

                if (productPage != null && productPage.DesignImage != null)
                {
                    map.ImageURL = productPage.DesignImage.URL;
                }

                TemplatePage templatePage = repository.GetByKey<TemplatePage>(templatePageId);

                if (designPage != null && templatePage != null)
                {
                    PrintSize printSize = printerPage.PrintSize;

                    Rect fittedRect = PrintHelper.fitRect(printSize.WebsiteWidthInch, printSize.WebsiteHeightInch,
                        templatePage.TemplateWidthPix, templatePage.TemplateHeightPix);

                    // Calculate the Offset and Scale
                    float offsetXInch = designPage.ImageOffsetXInch + fittedRect.OffsetX + (printerPage.PrintSize.WebsiteOffsetXInch ?? 0);
                    float offsetYInch = designPage.ImageOffsetYInch + fittedRect.OffsetY + (printerPage.PrintSize.WebsiteOffsetYInch ?? 0);

                    if (templatePage.ThumbnailURL != null)
                    {
                        map.TemplateURL = templatePage.ThumbnailURL;
                        map.TempalteScale = 1;
                    }

                    // Set URLs
                    if (productPage.DesignImage != null)
                    {
                        float imageDPI = designPage.DesignImageDPI;

                        map.TemplateOffsetXPix = offsetXInch * imageDPI;
                        map.TemplateOffsetYPix = offsetYInch * imageDPI;

                        float widthPix = imageDPI * fittedRect.Width;
                        map.TempalteScale = (float)widthPix / templatePage.ThumbnailWidthPix;
                    }
                }

                map.DesignableProductId = product.DesignableProductId;

                return map;
            }
        }

        static public Bitmap RenderMap(Template2ProductMap map)
        {
            string imageURL = @"..\" + map.ImageURL;
            string templateUrl = @"..\" + map.TemplateURL;

            string fullImageUrl = HttpContext.Current.Server.MapPath(imageURL);
            string fullTemplateUrl = HttpContext.Current.Server.MapPath(templateUrl);

            bool hasImage = !string.IsNullOrEmpty(map.ImageURL);
            bool hasTemplate = !string.IsNullOrEmpty(map.TemplateURL);

            // Case no product and no templage
            if (!hasImage && !hasTemplate)
            {
                var emptyImage = new Bitmap(100, 100);
                Graphics eg = Graphics.FromImage(emptyImage);
                eg.DrawEllipse(Pens.Black, 10, 10, 80, 80);
                return emptyImage;
            }

            // Case there is no product and there is a templage
            if (!hasImage && hasTemplate)
            {
                return new Bitmap(fullTemplateUrl);
            }

            // Case there is a product and no templage
            if (hasImage && !hasTemplate)
            {
                return new Bitmap(fullImageUrl);
            }

            
            // Case there are both prodct and templage
            Bitmap image = new Bitmap(fullImageUrl);
            Bitmap template = new Bitmap(fullTemplateUrl);

            Graphics g = Graphics.FromImage(image);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.DrawImage(template, map.TemplateOffsetXPix, map.TemplateOffsetYPix, template.Width * map.TempalteScale, template.Height * map.TempalteScale);
            
            return image;
        }

        static public Bitmap RenderProductByIdx(int templateId = 1, int templatePageIdx = 1, int productId = 1, int productPageIdx = 1)
        {
            var map = DesignTemplatesLogic.Template2Product(templateId, templatePageIdx, productId, productPageIdx);

            return RenderMap(map);
        }

        static public Bitmap RenderProductImage(int templatePageId, int designPageId)
        {
            var map = DesignTemplatesLogic.Template2ProductByDesignPageId(templatePageId, designPageId);

            return RenderMap(map);
        }

        static public Bitmap GetTemplateFullImage(int templatePageId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var templatePage = repository.GetByKey<TemplatePage>(templatePageId);

                string ImageURL = @"..\" + templatePage.ImageURL;

                Bitmap image = new Bitmap(HttpContext.Current.Server.MapPath(ImageURL));

                return image;
            }
        }

        static public byte[] BitmapToByteArray(Bitmap bitmap)
        {
            byte[] byteArray = new byte[0];
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                stream.Close();
                byteArray = stream.ToArray();
            }
            return byteArray;
        }
    }
}
